package panda.client.ui.widgets;

import java.util.ArrayList;
import java.util.List;

import panda.client.JSNI;
import panda.client.Cardpanda;
import panda.client.engine.MagicCard;
import panda.client.engine.MagicCardDB;
import panda.client.enumerations.MagicSet;
import panda.client.enumerations.ZIndexLevel;
import panda.client.listeners.LabelWithContainerMouseListener;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Dialog for loading MagicCardTokens from server.
 * 
 * @author zane.tian@gmail.com
 */
public class TokenSummonDialog extends Composite {
	private boolean open;

	private List<MagicCard> clientTokenDB;
	private VerticalPanel shell;
	private HorizontalPanel hp;
	private SuggestBox box;
	private Button submit;
	private Label dragLabel;

	public TokenSummonDialog() {
		clientTokenDB = new ArrayList<MagicCard>();
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.LORWYN_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.MORNINGTIDE_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.SHADOWMOOR_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.EVENTIDE_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.SHARDS_OF_ALARA_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.CONFLUX_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.ALARA_REBORN_TOKENS));
		clientTokenDB.addAll(MagicCardDB.getCardsFromSet(MagicSet.M_10_TOKENS));

		/* TODO add tokens from M10 when the HQ scans are released! */

		MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
		for(MagicCard token : clientTokenDB) {
			oracle.add(token.toString());
		}

		box = new SuggestBox(oracle);
		box.setAnimationEnabled(false);

		submit = new Button("Reveal");
		submit.addClickListener(new ClickListener() {
			private boolean found = false;

			public void onClick(Widget sender) {
				for(MagicCard token : clientTokenDB) {
					if(token.toString().equals(box.getText())) {
						found = true;
						/* we know that clientTokenDB is actually a Set (no duplicates) */
						/* clientTokenDB is not implemented as a set because JRE Emulation might not support it */
						
						Cardpanda.grabTokenByExactIDFromServer(token.getName(), token.getMagicSet(), token.getID());
						break;
					}
				}

				if(!found) {
					NoteTip.get().logPersonalNote("No matching token found.", true);
				}
			}
		});

		DOM.setStyleAttribute(submit.getElement(), "border", "1px solid black");
		DOM.setStyleAttribute(submit.getElement(), "margin-left", "2px");

		hp = new HorizontalPanel();
		hp.setSpacing(2);
		hp.add(box);
		hp.add(submit);

		open = false;

		dragLabel = new Label("Enter a Token Name");
		JSNI.disableSelection(dragLabel.getElement());
		
		NoteTip.setShadedStyle(dragLabel.getElement());
		DOM.setStyleAttribute(dragLabel.getElement(), "borderBottom", "1px solid black");

		shell = new VerticalPanel();
		DOM.setStyleAttribute(shell.getElement(), "border", "1px solid black");
		shell.add(dragLabel);
		shell.add(hp);
		initWidget(shell);
		hide();

		DOM.setStyleAttribute(this.getElement(), "zIndex", String.valueOf(ZIndexLevel.TOKENMENU.getZIndex()));
		dragLabel.addMouseListener(new LabelWithContainerMouseListener(this));
	}

	public void hide() {
		open = false;
		setVisible(false);
	}

	public void show() {
		open = true;
		setVisible(true);
		
		DeferredCommand.addCommand(new Command() {
		    public void execute() {
		       box.setFocus(true);
		     }
		});
	}

	public boolean isOpen() {
		return open;
	}
}